
package futbol.tacticas.concursantes2007.Corinthians;
import futbol.General;
import futbol.tacticas.concursantes.Tactica;

import java.awt.*;
import java.util.LinkedList;
import java.util.Vector;
import futbol.tacticas.*;

/**
 *
 * @author Administrador
 */
public class Corinthians implements Tactica {
    
    int color=0;
    
    private int nValores[][]={
        {48,0,7},  // Jugador 1[0]
        {69,69,7},  // Jugador 2[1]
        {69,-69,7},  // Jugador 3[2]
        {20,0,4},  // Jugador 4[3]
        {15,89,4},  // Jugador 5[4]
        {-90,0,4},  // Jugador 6[5]
        {-64,16,6},  // Jugador 7[6]
        {-40,-16,4},  // Jugador 8[7]
        {-112,30,4},  // Jugador 9[8]
        {-150,0,4},  // Jugador 10[9]
        {-150,20,6}  // Jugador 11[10]
    };
    
    private int nValores1[][]={
        {48,30},  // Jugador 11[10]
        {69,45},  // Jugador 10[9]
        {69,-45},  // Jugador 9[8]
        {20,0},  // Jugador 8[7]
        {15,89},  // Jugador 7[6]
        {-64,16},  // Jugador 6[5]
        {-90,0},  // Jugador 5[4]
        {-40,-16},  // Jugador 4[3]
        {-150,30},  // Jugador 3[2]
        {-150,0},  // Jugador 2[1]
        {-150,20}  // Jugador 1[0]
    };
    private int nValores2[][]={
        {48,0},  // Jugador 11[10]
        {69,90},  // Jugador 10[9]
        {59,-90},  // Jugador 9[8]
        {20,0},  // Jugador 8[7]
        {15,89},  // Jugador 7[6]
        {-64,16},  // Jugador 6[5]
        {-90,0},  // Jugador 5[4]
        {-40,-16},  // Jugador 4[3]
        {-150,-20},  // Jugador 3[2]
        {-150,0},  // Jugador 2[1]
        {-150,20}  // Jugador 1[0]
    };
    
    
    private int golFavor=0;
    private int golContra=0;
    private Point bolaAnt;
    private Point bolaAntGol;
    
    public Color getColor1(){
        return Color.GREEN;
    }
    
    public Color getColor2(){
        return Color.BLUE;
    }
    
    public Color getColorNumero(){
        color=(color+1)%256;
        return new Color(0,0,color);
    }
    
    public String getNombre(){
        return "Corinthians";
    }
    
    public int getXInicial(int n) {
        return nValores[n][0];
    }

    public int getYInicial(int n) {
        return nValores[n][1];
    }

    public int getFuerza(int n) {
        return nValores[n][2];
    }
    private int estrategia=0;
    private int numEstrategias=3;
    private int conta=0;
    private Point portero2;
    public Vector<Comando> getComandos(SituacionJugadores sj) {
        
        if (conta==0){
            bolaAnt=new Point();
            bolaAntGol=new Point();
            portero2=new Point();
        }
        conta++;
        Vector<Comando> com=new Vector();
        //Posicionamiento
        for (int n=0;n<11;n++){
            if (estrategia==0)
                com.add(new ComandoIrA(n,nValores[n][0],nValores[n][1]));
            if (estrategia==1 || estrategia==3)                
                com.add(new ComandoIrA(n,nValores1[n][0],nValores1[n][1]));
            if (estrategia==2)                
                com.add(new ComandoIrA(n,nValores2[n][0],nValores2[n][1]));
        }
        
        Point bola=sj.getBola();
        Point jugadores[]=sj.getMisJugadores();
        Point contrarios[]=sj.getContrario();
        
        if (bolaAntGol.x>150 && bola.x<40)golFavor++;
        if (bolaAntGol.x<-150 && bola.x>-40)  golContra++;
        bolaAntGol.x=bola.x;
        if (conta%5==0){
            bolaAnt.x=bola.x;
            bolaAnt.y=bola.y;
        }
        if (conta%300==0){
            if (golFavor<golContra){
                estrategia=(estrategia+1)%numEstrategias;
            }
            golFavor=golContra=0;
        }

        //Movimiento portero
        int y=(int)(bola.getY()/2);
        if (y<-20) y=-20;
        if (y>20) y=20;
        
        
        com.add(new ComandoIrA(10,nValores[10][0], y));
        portero2=trayectoriaTiro(bolaAnt, bola);
        com.add(new ComandoIrA(9,nValores[9][0], portero2.y));
        if (estrategia==3)com.add(new ComandoIrA(8,-140, portero2.y));
        
        boolean golpeado=false;
        
         
         
        //Movimiento mas cercano a la bola
        int nJug=sj.getMasCercanoDeBola();
        int delanteroCerca=this.encuentraDelantero(sj);
        if (jugadores[6].distance(bola)<20) nJug=6;
        double diferencia=jugadores[delanteroCerca].getLocation().distance(bola);
        if (diferencia<12) nJug=delanteroCerca;
        com.add(new ComandoIrA(nJug,bola.getX(), bola.getY()));
        if (diferencia<55) com.add(new ComandoIrA(delanteroCerca,bola.getX(), bola.getY()));
        
        int otroDel=-1;
        if (!golpeado && nJug<=2){
            if (estrategia==2){
                if (nJug==0)  com.add(new ComandoTiroAPuerta(nJug,(int)(Math.random()*5)));
                if (nJug==1){
                    otroDel=this.encuentraDesmarque(sj, 0, 0);
                    if (otroDel!=-1) com.add(new ComandoPase(nJug, otroDel));
                    else {
                        otroDel=this.encuentraDesmarque(sj, 2, 2);
                        if (otroDel!=-1) com.add(new ComandoPase(nJug, otroDel));
                        else com.add(new ComandoTiroAPuerta(nJug,(int)(Math.random()*5)));
                    }
                }
                if (nJug==2){
                    otroDel=this.encuentraDesmarque(sj, 0, 0);
                    if (otroDel!=-1) com.add(new ComandoPase(nJug, otroDel));
                    else {com.add(new ComandoTiroAPuerta(nJug,(int)(Math.random()*5)));
                    }
                }
            }
            com.add(new ComandoTiroAPuerta(nJug,(int)(Math.random()*5)));
            golpeado=true;
        }
            
        if (!golpeado && nJug==10){
            golpeado=true;
            int pasaA=this.encuentraDesmarque(sj, 6, 6);
            if (pasaA==-1) pasaA=this.encuentraDesmarque(sj, 0, 8);
            if (pasaA==-1) com.add(new ComandoGolpearBola(10, -60, 120));
            else  com.add(new ComandoPase(10, 6));
        }
        
        if (!golpeado && nJug==6){
            com.add(new ComandoPase(nJug, this.encuentraDelantero(sj)));
            golpeado=true;
        }
        
        if (!golpeado && jugadores[nJug].x>50){
            if (contrarios[sj.getContrarioMasCerca(delanteroCerca)].distance(jugadores[delanteroCerca])<35){
                com.add(new ComandoPase(nJug, this.encuentraDelantero(sj)));
                golpeado=true;
            }
        }
        
        Point pelotaPos=new Point();
        int aCubrir=6;
        if (estrategia==3) aCubrir=5;
        LinkedList <Point> peaRival=delanterosRivales(sj, aCubrir);
        int m=8;
        if (estrategia==3)m=7;
        for (Point po : peaRival){
            if (bola.x>po.x) pelotaPos.x=10;
            else pelotaPos.x=-10;
            if (bola.y>po.y) pelotaPos.y=10;
            else pelotaPos.y=-10;
            if (m!=nJug)       com.add(new ComandoIrA(m, po.x+pelotaPos.x, po.y+pelotaPos.y));
            m--;
        }
        
        if (!golpeado && this.nValores[nJug][2]==8 && nJug>2){
            Point d=this.pasoLejano(sj);
            com.add(new ComandoGolpearBola(nJug, d.x, d.y));
            golpeado=true;
        }
        
        int nDir[][]={{30,0},
                    {30, 30},
                    {30, -30},
                    {0,30},
                    {0,-30},
                    {-30, 30},
                    {-30, 0},
                    {-30,0}};
        int nDis=30;
        
        if (!golpeado && General.getDistancia(bola.getX(), bola.getY(), jugadores[nJug].getX(), jugadores[nJug].getY())<10)
            for (int n=0;n<nDir.length-1 && !golpeado ;n++){
                double xN=corregirLateral(160,jugadores[nJug].getX()+nDir[n][0]);
                double yN=corregirLateral(120,jugadores[nJug].getY()+nDir[n][1]);
                int nJC= sj.getContrarioMasCerca(xN, yN);
                if (General.getDistancia(xN, yN, contrarios[nJC].getX(), contrarios[nJC].getY())>nDis){
                    com.add(new ComandoGolpearBola(nJug, xN, yN));
                    golpeado=true;
                }
            }
        
        if (!golpeado && nJug>2){
            Point p=this.desmarque(sj);
            if (p!=null){
                com.add(new ComandoGolpearBola(nJug, p.x, p.y));
                golpeado=true;
            }
            com.add(new ComandoTiroAPuerta(nJug, 0));    
        }        
        return com;
    }
    
    private Point desmarque(SituacionJugadores sj){
        Point p=new Point();
        for (int i=0; i<105; i++){
            p.x=(int)(sj.getBola().getX()+Math.random()*(340-sj.getBola().getX()));
            p.y=(int)(Math.random()*240)-120;
            int contrario=sj.getContrarioMasCerca(p.x, p.y);
            int rivaldista=(int)((p.getX()-sj.getContrario()[contrario].x)*(p.getX()-sj.getContrario()[contrario].x)+(p.getY()-sj.getContrario()[contrario].y)*(p.getY()-sj.getContrario()[contrario].y));
            int mio=sj.getMiJugadorMasCerca(p.x, p.y);
            int midista=(int)((p.getX()-sj.getMisJugadores()[mio].x)*(p.getX()-sj.getMisJugadores()[mio].x)+(int)(p.getY()-sj.getMisJugadores()[mio].y)*(p.getY()-sj.getMisJugadores()[mio].y));
            if (midista<rivaldista)  return p;      
        }
        return null;
    }
    
    private LinkedList<Point> delanterosRivales(SituacionJugadores sj, int aCubrir){
        LinkedList<Point> sol=new LinkedList<Point>();
        int min, minjug;
        boolean juga[]={false, false, false, false, false, false, false, false, false, false, false};
        for (int i=0; i<aCubrir; i++){
            min=9999;
            minjug=11;
            for (int j=0; j<11; j++){
                if (!juga[j] && sj.getContrario()[j].getX()<min){
                    min=(int)sj.getContrario()[j].getX();
                    minjug=j;
                }
            }
            sol.add(sj.getContrario()[minjug]);
            juga[minjug]=true;
        }
        return sol;      
    }
    
    private Point pasoLejano(SituacionJugadores sj){
        Point sol=new Point();
        double aux;
        double max=0;
        for (int i=0; i<9; i++){
            aux=sj.getBola().distance(sj.getMisJugadores()[i].getLocation());
            if (sj.getMisJugadores()[i].x>sj.getBola().x && aux>max){
                max=aux;
                sol.x=sj.getMisJugadores()[i].x;
                sol.y=sj.getMisJugadores()[i].y;
            }
        }
        return sol;
    }
    
    private int encuentraDelantero(SituacionJugadores sj){
        double mindist, aux;
        int del=0;
        mindist=9999;
        for (int i=0; i<3; i++){
           aux=sj.getMisJugadores()[i].distance(sj.getBola());
           if (aux<mindist){mindist=aux; del=i;}
        }
        return del;
    }
    private double corregirLateral(double limite, double x){
        if (x>limite) return limite*2-x;
        if (x<-limite) return -limite*2-x;
        return x;
    }
    
    
    private Point trayectoriaTiro(Point a, Point b){
        Point sol=new Point();
        sol.x=-160;
        double incX=b.x-a.x;
        double trayectoriaX=b.x+160;
        double factor=trayectoriaX/incX;
        double incY=a.y-b.y;
        sol.y=(int)(b.y+incY*factor);
        if (sol.y<-35)sol.y=-35;
        if (sol.y>35) sol.y=35;
        return sol;
    }
    
    private int encuentraDesmarque(SituacionJugadores sj, int inicio, int fin){
        double mindist, aux;
        int del=-1;
        mindist=9999;
        for (int i=inicio; i<=fin; i++){
           if(sj.getContrario()[sj.getContrarioMasCerca(i)].distance(sj.getMisJugadores()[i])<20) continue; //si el contrario est a ms de 20 us de mi jugador:
           aux=sj.getMisJugadores()[i].distance(sj.getBola());
           if (aux<mindist){mindist=aux; del=i;}
        }
        return del;
    }
}
